昨天提到JavaScript可以將函式當作引數來傳遞,
當把一個函式傳給另一個函式呼叫時叫做回呼(callback)
,而傳給別的函式呼叫的函式叫做回呼函式
在陣列有許多接收回呼函式當作參數的方法,並用該回呼函式對陣列進行處理,
懂這些方法後就不用每次在那邊寫for迴圈在leetcode用for迴圈解陣列題的傻子就是我
每次都用很簡單的陣列當範例還蠻無聊的,這次弄了9個人的物件陣列,每個人的屬性有名字、收入、
年齡、跟喜歡的顏色(紅黃藍其中一種)
以下範例都是用這個陣列:
let people = [
{
name: 'Bright',
salary: 45777,
age: 35,
favoriteColor: 'red',
},
{
name: 'Strickland',
salary: 55953,
age: 33,
favoriteColor: 'blue',
},
{
name: 'Russo',
salary: 29463,
age: 23,
favoriteColor: 'blue',
},
{
name: 'Beach',
salary: 64735,
age: 30,
favoriteColor: 'red',
},
{
name: 'Witt',
salary: 57101,
age: 40,
favoriteColor: 'red',
},
{
name: 'Charles',
salary: 45492,
age: 27,
favoriteColor: 'yellow',
},
{
name: 'Wyatt',
salary: 36845,
age: 20,
favoriteColor: 'yellow',
},
{
name: 'Jefferson',
salary: 29756,
age: 33,
favoriteColor: 'yellow',
},
{
name: 'Small',
salary: 67155,
age: 22,
favoriteColor: 'red',
},
];
最簡單的一種方法,把陣列內每個元素都丟給函式執行一次
function log(person) {
console.log(
`名稱:${person.name},年紀:${person.age},薪水:${person.salary},喜歡的顏色:${person.favoriteColor}`
);
}
people.forEach(log);
/* 執行結果
名稱:Bright,年紀:35,薪水:45777,喜歡的顏色:red
名稱:Strickland,年紀:33,薪水:55953,喜歡的顏色:blue
名稱:Russo,年紀:23,薪水:29463,喜歡的顏色:blue
名稱:Beach,年紀:30,薪水:64735,喜歡的顏色:red
名稱:Witt,年紀:40,薪水:57101,喜歡的顏色:red
名稱:Charles,年紀:27,薪水:45492,喜歡的顏色:yellow
名稱:Wyatt,年紀:20,薪水:36845,喜歡的顏色:yellow
名稱:Jefferson,年紀:33,薪水:29756,喜歡的顏色:yellow
名稱:Small,年紀:22,薪水:67155,喜歡的顏色:red
*/
上面宣告了一個叫做log
的函式來印出單人的資料,forEach
方法會將people陣列中每個元素依序當成引數來呼叫log
,把所有人的資料印出
map()
方法forEach()
都是把每個元素當引數傳給函式,
不同的是map()
會把所有的回傳值集合成一個陣列回傳,會收到一個跟原本相同長度的陣列
let peopleName = people.map((person) => person.name);
console.log(peopleName);
//["Bright", "Strickland", "Russo", "Beach", "Witt", "Charles", "Wyatt", "Jefferson", "Small"]
這次的回呼函式只取出name
屬性,map()
把全部名稱集合的陣列給回傳
find()
跟filter()
會使用使用回呼函式來把陣列的值做測試,find()
方法會把第一個通過測試(回傳true
)的元素回傳,
而filter()
方法會把符合測試的全部結果建立新陣列回傳,
在寫前端網頁時,可以用filter()
來實作各大網站常有篩選特定結果。
let firstPersonLikeYellow = people.find(
(person) => person.favoriteColor === 'yellow'//測試喜歡的顏色是不是黃色
);
log(firstPersonLikeYellow);
//執行結果 找出第一個喜歡黃色的人
//名稱:Charles,年紀:27,薪水:45492,喜歡的顏色:yellow
let peopleLikeYellow = people.filter(
(person) => person.favoriteColor === 'yellow'
);
peopleLikeYellow.forEach(log);
/*執行結果 把喜歡黃色的人篩選出來了
名稱:Charles,年紀:27,薪水:45492,喜歡的顏色:yellow
名稱:Wyatt,年紀:20,薪水:36845,喜歡的顏色:yellow
名稱:Jefferson,年紀:33,薪水:29756,喜歡的顏色:yellow
*/
這兩種方法也會用回呼函式來做測試,every()
在全部元素都符合測試時才會回傳true
,否則回傳false
some()
只要有一個元素符合測試就會回傳true
console.log(people.every((person) => person.age >= 20));
//測試是否所有人都成年(20歲以上) 結果為true
console.log(people.every((person) => person.salary > 35000));
//測試是否全部月薪都有超過35000 結果false
console.log(people.some((person) => person.salary > 35000));
//但測試是否有人月薪超過35000 結果為true
console.log(people.some((person) => person.favoriteColor === 'pink'));
//看有沒有人喜歡粉紅色 結果false
sort()
方法可以把陣列作排序,如果沒有傳函式給sort()
時會用預設的方式排序,
可以用傳入一個排序用的函式來自定排序的規則。
//排序的規則
function 排序函式(a, b) {
//如果回傳值 <0 a排在b左邊
//如果回傳值 =0 排序不變
//如果回傳值 >0 a排在b右邊
}
function sortBySalary(a, b) { //使用薪水排列 由低到高
return a.salary - b.salary;
}
function sortByName(a, b) { //使用名字排列 從a排到z
return a.name[0] > b.name[0] ? 1 : -1;
}
people.sort(sortBySalary);
people.forEach(log);
/*薪水排列的結果
名稱:Russo,年紀:23,薪水:29463,喜歡的顏色:blue
名稱:Jefferson,年紀:33,薪水:29756,喜歡的顏色:yellow
名稱:Wyatt,年紀:20,薪水:36845,喜歡的顏色:yellow
名稱:Charles,年紀:27,薪水:45492,喜歡的顏色:yellow
名稱:Bright,年紀:35,薪水:45777,喜歡的顏色:red
名稱:Strickland,年紀:33,薪水:55953,喜歡的顏色:blue
名稱:Witt,年紀:40,薪水:57101,喜歡的顏色:red
名稱:Beach,年紀:30,薪水:64735,喜歡的顏色:red
名稱:Small,年紀:22,薪水:67155,喜歡的顏色:red
*/
people.sort(sortByName);
people.forEach(log);
/*名稱排列的結果
名稱:Beach,年紀:30,薪水:64735,喜歡的顏色:red
名稱:Bright,年紀:35,薪水:45777,喜歡的顏色:red
名稱:Charles,年紀:27,薪水:45492,喜歡的顏色:yellow
名稱:Jefferson,年紀:33,薪水:29756,喜歡的顏色:yellow
名稱:Russo,年紀:23,薪水:29463,喜歡的顏色:blue
名稱:Small,年紀:22,薪水:67155,喜歡的顏色:red
名稱:Strickland,年紀:33,薪水:55953,喜歡的顏色:blue
名稱:Witt,年紀:40,薪水:57101,喜歡的顏色:red
名稱:Wyatt,年紀:20,薪水:36845,喜歡的顏色:yellow
*/